import { defineStore } from 'pinia';
import { getToken, removeToken, setToken } from '../utils/token-utils';
import type { UserInfoState } from './interface';
import { ElMessage } from 'element-plus'
import { staticRoutes, allAsyncRoutes, anyRoute } from '@/router/routes'
//登录请求函数|获取用户信息函数|退出登录的函数
import { reqLogin, reqUserInfo, reqLogOut } from '@/api/acl/login';
import _ from 'lodash';
import router from '@/router';
//计算出当前用户将来需要动态追加的异步路由结果
//第一个参数:路由文件里面对外暴露的全部异步路由组件   
//第二个参数:当用户登录成功，用户信息里面包含的异步路由信息(需要动态注册的信息)
const findUserAsyncRoutes = (allAsyncRoutes: any, routes: any) => {
  //过滤出用户需要动态添加的异步路由
  return allAsyncRoutes.filter((item: any) => {
    //item:过滤一级路由
    if (routes.indexOf(item.name) != -1) {
      //接着过滤二级、三级、四级、N路由
      //代表子路由
      if (item.children && item.children.length > 0) {
        //上一级的children重新赋值
        item.children = findUserAsyncRoutes(item.children, routes);
      }
      return true;
    }
  })
}





export const useUserInfoStore = defineStore('userInfo', {
  state: (): UserInfoState => ({
    token: getToken() as string,//token
    name: '',//用户信息名字
    avatar: '',//用户头像
    menuRoutes: [],//左侧菜单需要展示的数据
    buttonsList:[]
  }),

  actions: {
    //点击登录按钮:仓库要向服务器发请求登录请求----token
    async login(username: string, password: string) {
      //登录请求:如果登录成功，返回token
      //token:登录成功才会有token,令牌区分用户[唯一标识符]！！！
      //token:持久化存储
      try {
        //如果登录成功过
        let result = await reqLogin({ username, password });
        //仓库存储token
        this.token = result.token;
        //持久化存储数据token
        setToken(result.token);
        return 'ok'
      } catch (error) {
        //登录失败
        return Promise.reject('失败');
      }
    },

    //获取用户信息
    async getInfo() {
      try {
        //登录成功获取用户信息:切记别忘记携带token
        let result = await reqUserInfo();
        //获取用户信息:头像、名字
        this.name = result.name;
        this.avatar = result.avatar;
        //仓库存储当前用户按钮的权限
        this.buttonsList = result.buttons;
        // //先计算出当前用户需要展示的异步路由:定义异步路由与服务器返回的数据routes进行对比
        // //深拷贝:为了解决全部异步路由发生变化------>没有办法了，只能深拷贝，
        // //每一个用户对比的异步路由应该一样的！！！！！！！
        let userRegisterAsyncRoute = findUserAsyncRoutes(_.cloneDeep(allAsyncRoutes), result.routes);
        // //调用方法：动态添加用户注异步路由 + 任意路由
        this.setRoute([...userRegisterAsyncRoute, anyRoute]);
        // //左侧导航区域的菜单需要展示的数据
        this.menuRoutes = [...staticRoutes, ...userRegisterAsyncRoute]
        return 'ok'
      } catch (error) {
        return Promise.reject(error);
      }
    },

    //动态添加路由
    setRoute(registerRoute: any) {
      //用户A:B:C：最终需要动态追加的路由
      registerRoute.forEach((item: any) => {
        //动态追加异步路由(计算完毕的)
        router.addRoute(item);
      })
    }
    ,
    //退出登录按钮
    async reset() {

      try {
        //退出登录请求
        await reqLogOut();
        //删除本地存储的token
        removeToken();
        //情况仓库自身的关于用户信息的数据
        this.token = ''
        this.name = ''
        this.avatar = ''
        //重置路由
        this.resetRoute();
        return 'ok';
      } catch (error) {
        return Promise.reject(error);
      }

    },
    //重置路由方法
    resetRoute() {
      //当前用户退出登录，应该清空掉全部异步路由
      //获取当前用户全部路由信息
      let allRoutes = router.getRoutes();
      //用户退出登录:全部的路由清除
      allRoutes.forEach((item: any) => {
        //全部删除路由:通过路由名字删除
        router.removeRoute(item.name);
      });
      //常量路由:动态添加上
      staticRoutes.forEach((item: any) => {
        router.addRoute(item);
      });
    }
  },
});
